package com.nxy.cpfsfe.util;

import com.adtec.starring.datapool.CompSDO;
import com.adtec.starring.datapool.EPOper;
import com.adtec.starring.exception.BaseException;
import com.adtec.starring.pubmethod.Message;
import com.adtec.starring.struct.dataelem.DataElement;
import com.adtec.starring.struct.dta.DtaInfo;
import com.adtec.starring.tool.DTATool;
import com.adtec.starring.util.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.nxy.cpfsfe.busi.btmgtsk.TbSelfmntnProcBean;
import com.nxy.cpfsfe.enumtype.RespCd;
import com.nxy.cpfsfe.enumtype.RpcOutputInfoEnum;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 
 * RPC调用网关服务
 * @author nxygyzd
 *
 */
public class RpcCommUtil {
	//初始化对象
	private static RpcCommUtil rpcCommUtil = new RpcCommUtil();
	//构造函数私有化
	private RpcCommUtil (){
		
	}
	//公开获取单例对象函数
	public static RpcCommUtil  getInstance(){
		
		 return rpcCommUtil;
	}
	
	private final static Logger LOGGER = LoggerFactory.getLogger(RpcCommUtil.class);	
		
	/**
	 * 
	 * rpc调用网关方法，需要在线程内设置好EPOper的所需参数值，默认不发送失败则加入补发表
	 * @param tpId 为线程中获取到的DtaInfo.getInstance().getTpId(); 
	 * @param outputName 接出点名称
	 * @param outPutSvr 接出点服务名
	 * @return
	 */
	public String rpcFeToGW(String tpId,String outputName,String outPutSvr) {
		return rpcFeToGW(tpId,outputName,outPutSvr,true);
	}
	/**
	 * rpc调用网关方法，需要在线程内设置好EPOper的所需参数值
	 * @param tpId 为线程中获取到的DtaInfo.getInstance().getTpId();
	 * @param outputName 接出点名称
	 * @param outPutSvr 接出点服务名
	 * @param flag 是否加入补发表。
	 * @return
	 */
	public String rpcFeToGW(String tpId,String outputName,String outPutSvr,boolean flag){
		String rspsCd ="";
		try {
			 if(StringUtils.isEmpty((String) EPOper.get(tpId, "ReqBean[0].head[0].rcvAppCd"))){
				 LOGGER.error("接出点ReqHead头信息rcvAppCd属性字段不能为空");
				 return RespCd.NCPO6468 +"|rcvAppCd属性字段不能为空";
			 }
	         if(StringUtils.isEmpty(outputName)||StringUtils.isEmpty(outPutSvr)){
	       		LOGGER.error("接出点名称OutputName或者接出点OutPutSvr服务名都不能为空");
	       		return RespCd.NCPO6468+"|OutputName或者接出点OutPutSvr服务名都不能为空";
			 }
			
			 EPOper.put(tpId, "ReqBean[0].head[0].servEcd", outPutSvr);//不要删除，会影响赋值
			 LOGGER.info("FE接出到GW的rpc服务报文头servEcd：[{}],sndAppCd：[{}],rcvAppCd：[{}],reqServCd：[{}],initrSeqno：[{}]",
					 (String) EPOper.get(tpId, "ReqBean[0].head[0].servEcd"),
					 (String) EPOper.get(tpId, "ReqBean[0].head[0].sndAppCd"),
					 (String) EPOper.get(tpId, "ReqBean[0].head[0].rcvAppCd"),
					 (String) EPOper.get(tpId, "ReqBean[0].head[0].reqServCd"),
					 (String) EPOper.get(tpId, "ReqBean[0].head[0].initrSeqno"));
			 LOGGER.info("FE接出到GW的rpc服务报文：{}",(String) EPOper.getCompSDO(tpId, "ReqBody").getValue("BizMsg"));
		     DTATool dtaTool = (DTATool) SpringUtil.getBean("dtaTool");
		     dtaTool.callOutPut(outputName, outPutSvr);
		     LOGGER.debug("FE接出到GW的rpc服务结束......");		     
		     rspsCd =(String) EPOper.get(tpId, "RspBean[0].head[0].rspsCd");
			 if(!RespCd.NCPI0000.equals(rspsCd)){
				LOGGER.error("FE接出到GW的rpc服务的返回应答码rspsCd=[{}]",rspsCd);
			 }
		     if (!RespCd.NCPI0000.equals(rspsCd) && flag) {
				 //发送失败，登记补发表
				 TbSelfmntnProcBean.regTbSelfmntn((String) EPOper.getCompSDO(tpId, "ReqBody").getValue("BizMsg"), (String) EPOper.get(tpId, "ReqBean[0].head[0].sndAppCd"),(String) EPOper.get(tpId, "ReqBean[0].head[0].rcvAppCd"));
			 }
		} catch (Exception e) {
			LOGGER.info("FE接出到GW的rpc服务的返回应答码rspsCd=[{}]",rspsCd);
			LOGGER.error("FE接出到GW的rpc服务出现异常......",e);
			 if (!RespCd.NCPI0000.equals(rspsCd) && flag) {
					 //发送失败，登记补发表
				TbSelfmntnProcBean.regTbSelfmntn((String) EPOper.getCompSDO(tpId, "ReqBody").getValue("BizMsg"), (String) EPOper.get(tpId, "ReqBean[0].head[0].sndAppCd"),(String) EPOper.get(tpId, "ReqBean[0].head[0].rcvAppCd"));
			}
		}
		 LOGGER.info("FE接出到GW的rpc服务的返回应答码rspsCd=[{}]",rspsCd);
	     return rspsCd;
	}
	public String rpcFeToGWRetMsg(String tpId,String outputName,String outPutSvr){
		String rspsCd ="";
		String repMsg ="";
		try {
			if(StringUtils.isEmpty((String) EPOper.get(tpId, "ReqBean[0].head[0].rcvAppCd"))){
				LOGGER.error("接出点ReqHead头信息rcvAppCd属性字段不能为空");
				return RespCd.NCPO6468 +"|rcvAppCd属性字段不能为空";
			}
			if(StringUtils.isEmpty(outputName)||StringUtils.isEmpty(outPutSvr)){
				LOGGER.error("接出点名称OutputName或者接出点OutPutSvr服务名都不能为空");
				return RespCd.NCPO6468+"|OutputName或者接出点OutPutSvr服务名都不能为空";
			}

			EPOper.put(tpId, "ReqBean[0].head[0].servEcd", outPutSvr);//不要删除，会影响赋值
			LOGGER.info("FE接出到GW的rpc服务报文头servEcd：[{}],sndAppCd：[{}],rcvAppCd：[{}],reqServCd：[{}],initrSeqno：[{}]",
					(String) EPOper.get(tpId, "ReqBean[0].head[0].servEcd"),
					(String) EPOper.get(tpId, "ReqBean[0].head[0].sndAppCd"),
					(String) EPOper.get(tpId, "ReqBean[0].head[0].rcvAppCd"),
					(String) EPOper.get(tpId, "ReqBean[0].head[0].reqServCd"),
					(String) EPOper.get(tpId, "ReqBean[0].head[0].initrSeqno"));
			LOGGER.info("FE接出到GW的rpc服务报文：{}",(String) EPOper.getCompSDO(tpId, "ReqBody").getValue("BizMsg"));
			DTATool dtaTool = (DTATool) SpringUtil.getBean("dtaTool");
			dtaTool.callOutPut(outputName, outPutSvr);
			LOGGER.debug("FE接出到GW的rpc服务结束......");
			rspsCd =(String) EPOper.get(tpId, "RspBean[0].head[0].rspsCd");
			if(!RespCd.NCPI0000.equals(rspsCd)){
				LOGGER.error("FE接出到GW的rpc服务的返回应答码rspsCd=[{}]",rspsCd);
			}
            String  rspBody = EPOper.getCompSDO(tpId, "RspBody").toJSON();
			JSONObject jsonObject = JSON.parseObject(rspBody);
			JSONArray jsonArray = jsonObject.getJSONArray("RspBody");
			JSONObject repMsgJson =jsonArray.getJSONObject(0);
			repMsg = repMsgJson.get("BizMsg").toString();
			LOGGER.info("GW的返回响应服务报文：[{}]",repMsg);
		} catch (Exception e) {
			LOGGER.info("FE接出到GW的rpc服务的返回应答码rspsCd=[{}]",rspsCd);
			LOGGER.error("FE接出到GW的rpc服务出现异常......",e);
			throw new BaseException( RespCd.NCPO6047,"FE接出到GW的rpc服务出现异常");
		}
		LOGGER.info("FE接出到GW的rpc服务的返回应答码rspsCd=[{}]",rspsCd);
		return repMsg;
	}

	public static void main(String[] args) {
		String abc ="{\"RspBody\":[{\"BizMsg\":\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><transaction><header><msg><msgCd>CBS0003301</msgCd><seqNb>019120605867912</seqNb><sndMbrCd>6100</sndMbrCd><rcvMbrCd>0000</rcvMbrCd><sndAppCd>CBS</sndAppCd><rcvAppCd>NNS</rcvAppCd><sndDt>20191206</sndDt><refMsgCd>CBS0003300</refMsgCd><refSndMbrCd>0000</refSndMbrCd><refSndAppCd>NNS</refSndAppCd><refSndDt>20191206</refSndDt><refSeqNb>06CPFS000242700</refSeqNb><refCallTyp>SYN</refCallTyp><callTyp>SYN</callTyp></msg><ver>1.0</ver><pnt><sndDt>20191206</sndDt><sndTm>154403</sndTm><sndMbrCd>0000</sndMbrCd><rcvMbrCd>0000</rcvMbrCd><sndAppCd>ESB</sndAppCd><rcvAppCd>NNS</rcvAppCd></pnt><status><retCd>399999</retCd><desc>客户帐号[620000000000001]不存在</desc><mbrCd>6100</mbrCd><appCd>CBS</appCd></status></header><body><response><payBal></payBal><payAvlBal></payAvlBal><hostSeqNb></hostSeqNb><NCSSeqNb></NCSSeqNb><workDate></workDate><businessCode></businessCode><messageFlag></messageFlag><realTotalFee></realTotalFee></response></body></transaction>\"}]}";
		JSONObject jsonObject = JSON.parseObject(abc);
		JSONArray jsonArray = jsonObject.getJSONArray("RspBody");
//		jsonObject = jsonObject.get("RspBody").toString();
		JSONObject avn =jsonArray.getJSONObject(0);
		System.out.println(		avn.get("BizMsg").toString());

	}
	/**
	 * 
	 * rpc调用通用体系方法，需要在线程内设置好EPOper的所需参数值
	 * @param tpId 为线程中获取到的DtaInfo.getInstance().getTpId(); 
	 * @param outputName 接出点名称
	 * @param outPutSvr 接出点服务名
	 * @return
	 */
	public String rpcFeToSms(String tpId,String outputName,String outPutSvr){
		String rspsCd ="";
		try {
			 if(StringUtils.isEmpty((String) EPOper.get(tpId, "ReqBean[0].head[0].servEcd"))){
				 LOGGER.error("接出点ReqHead头信息servEcd属性字段不能为空");
				 throw new BaseException("00001","servEcd属性字段不能为空");

			 }
	         if(StringUtils.isEmpty(outputName)||StringUtils.isEmpty(outPutSvr)){
	       		LOGGER.error("接出点名称OutputName或者接出点OutPutSvr服务名都不能为空");
				 throw new BaseException("00001","OutputName或者接出点OutPutSvr服务名都不能为空");

			 }
			 LOGGER.debug("rpc调用通用体系方法开始......servEcd={}",(String) EPOper.get(tpId, "ReqBean[0].head[0].servEcd"));
			 LOGGER.debug("rpc调用通用体系方法报文头initrSeqno：{}",EPOper.get(tpId, "ReqBean[0].head[0].initrSeqno"));
		     DTATool dtaTool = (DTATool) SpringUtil.getBean("dtaTool");
		     dtaTool.callOutPut(outputName, outPutSvr);
		     LOGGER.debug("rpc调用通用体系方法结束......");	
//		     {"head":{"initrSeqno":"whj2019051712237aA1a5","servEcd":"mQry_SeqSn","rspsCd":"0000000","respsInfoDesc":"成功"},"body":{"seqNo":"000009"}}
//		     {"head":{"initrSeqno":"whj2019051712237aA1a5","servEcd":"mQry_SeqSn","rspsCd":"PCA3004","respsInfoDesc":"系统异常"}}
		     rspsCd =(String) EPOper.get(tpId, "RspBean[0].head[0].rspsCd");
		     DtaInfo dtaInfo = DtaInfo.getInstance();
			 Message msg = (Message) dtaInfo.getMessage();
		     if("0000000".equals(rspsCd)){
		    	    // 获取返回
		         byte[] valueByte = (byte[]) msg.getBody();
		         if (valueByte != null) {
		             LOGGER.debug(new String(valueByte));
		             // return;
		         }
		         JSONObject json = JSONObject.parseObject(valueByte, JSONObject.class);
		    	 String seqNo =json.getString("seqNo");
		    	 return seqNo;
		     }else{
		    	 String errmsg = (String) EPOper.get(tpId, "RspBean[0].head[0].respsInfoDesc");
		    	 LOGGER.error("rpc调用通用体系返回异常......",errmsg);
				 throw new BaseException(rspsCd,errmsg);
		     }
		} catch (Exception e) {
			 LOGGER.error("rpc调用通用体系方法出现异常......",e);
			 rspsCd ="00002|调用通用体系方法出现异常";
			 throw new BaseException(RespCd.NCPO6047,"调用通用体系方法出现异常");
		}	

//		 LOGGER.debug("rpc调用通用体系方法的返回应答rspsCd=[{}]",rspsCd);
//	     return rspsCd;
	}

	/**
	 * 定时器访问联机账务的访问通用体系服务
	 * @param seqNm
	 * @return
	 */
	public String rpcTimerToBat(String seqNm) {
		DtaInfo dtaInfo = DtaInfo.getInstance();
		String tpId = dtaInfo.getTpId();
		String rspsCd ="";
		String seqNo = "";
		try {
	   	     EPOper.put(dtaInfo.getTpId(), "ReqBean[0].head[0].servEcd",RpcOutputInfoEnum.Timer_To_Sms_Service.getCode());
	   	     EPOper.put(dtaInfo.getTpId(), "ReqBean[0].head[0].initrSeqno",DateUtil.getDateTime());
			 EPOper.put(dtaInfo.getTpId(), "ReqBean[0].head[0].reqUrl","");
			 LOGGER.info("定时器接出到联机账务系统访问通用体系服务报文头servEcd：{}",(String) EPOper.get(tpId, "ReqBean[0].head[0].servEcd"));
			 LOGGER.info("定时器接出到联机账务系统访问通用体系服务报文头initrSeqno：{}",EPOper.get(tpId, "ReqBean[0].head[0].initrSeqno"));
			 EPOper.getCompSDO(tpId, "ReqBody").setValue("BizMsg",seqNm);
		     DTATool dtaTool = (DTATool) SpringUtil.getBean("dtaTool");
		     dtaTool.callOutPut(RpcOutputInfoEnum.TIMER_SMS_OUTPUT.getCode(), RpcOutputInfoEnum.Timer_To_Sms_Service.getCode());
		     LOGGER.debug("Timer接出到联机账务访问通用体系服务结束......");
		     rspsCd =(String) EPOper.get(tpId, "RspBean[0].head[0].rspsCd");
		     if(RespCd.NCPI0000.equals(rspsCd)){
		    	 CompSDO outputSdo = EPOper.getCompSDO(tpId, "RspBody");
		    	 seqNo =(String) outputSdo.getValue("BizMsg"); 
		     }
		    
		} catch (Exception e) {
			 LOGGER.error("Timer接出到ola的rpc服务出现异常......",e);
			 rspsCd = RespCd.NCPO6047+"|定时调度调用联机账务访问通用体系服务异常";
			 throw new BaseException(RespCd.NCPO6047,rspsCd);
		}	

		 LOGGER.info("Timer接出到联机账务访问通用体系服务的返回应答码rspsCd=[{}]",rspsCd);
	     return seqNo;
	}
	

}
